package howl.adaptor;

import java.util.ArrayList;
import java.util.List;

import howl.types.*;

import com.google.appengine.api.users.User;
import compiler.exceptions.HowlModelException;
import compiler.nonterminals.CreateStmt;
import compiler.nonterminals.DeleteStmt;
import compiler.nonterminals.InsertStmt;
import compiler.terminals.DataDecl;
import compiler.terminals.DataValue;

import Pachube.Data;
import Pachube.Feed;
import Pachube.Pachube;
import Pachube.PachubeException;

public class PachubeAdaptor extends SimplexAdaptor {

	private Pachube p;

	public PachubeAdaptor(HowlUser u) {
		super(u);
		this.p = new Pachube(u.getPachubeKey());
	}


	private boolean doCreate(TableDescriptor td) {

		try {
			Feed f = new Feed();
			f.setTitle(td.getName());
			ArrayList<String> its = td.getStringmapper();

			for (String s : its) {
				Data d = new Data();
				d.setTag(s);
				d.setValue(0.0);
				f.addData(d);
			}
			f = this.p.createFeed(f);
			//td = this.model.getTableDescriptor(td.getName());
			td.setPachubeFeedID(f.getId());
			this.model.getPm().close();
		} catch (PachubeException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	private boolean doDelete(String t) {
		TableDescriptor td;
		try {
			td = this.model.getTableDescriptor(t);
			if(td.getPachubeFeedID() != null)
				p.deleteFeed(td.getPachubeFeedID());
		} catch (HowlModelException e) {
			e.printStackTrace();
			return false;
		}
		return true;

	}

	private boolean doInsert(Insert i) {

		try {
			TableDescriptor td = null;
			ArrayList l = (ArrayList) i.getItems();
			if (l.size() > 0) {
				if (l.get(0) instanceof Entry) {
					td = this.model.getTableDescriptor(((Entry) l.get(0))
							.getParentID());
				} else if (l.get(0) instanceof Datum) {
					td = this.model.getTableDescriptor(((Datum) l.get(0))
							.getGrandParentID());
				}
				if(td.getPachubeFeedID() != null) {
				Feed f = p.getFeed(td.getPachubeFeedID());
				Datum d = null;
				for(int j = 0; j<l.size() ; j++) {
					if(l.get(j) instanceof Datum) {
						d = ((Datum)l.get(j));
						f.updateDatastream(d.getName(),d.getValue());
					}
				}
				}
			}
		} catch (PachubeException e) {
			e.printStackTrace();
			return false;
		} catch (HowlModelException e) {
			e.printStackTrace();
			return false;
		}
		return true;

	}


	@Override
	public void doCreate(CreateStmt ht) {
		try {
		TableDescriptor td = this.model.getTableDescriptor(ht.getFeedname().getFeedname()+ "@"
				+ this.user.getEmailAddress().split("@")[0]);
		//td.setOwner(this.user.getUsers());
		/*ArrayList<String> names = new ArrayList<String>();
		ArrayList<Unit> units = new ArrayList<Unit>();

		List<DataDecl> decs = ht.getDeclarations();
		for (int i = 0; i < decs.size(); i++) {
			DataDecl d = decs.get(i);
			names.add(d.getName());
			units.add(d.getDimension());
		}
		td.setUnitmapper(units);
		td.setStringmapper(names);*/
		this.doCreate(td);
		} catch (HowlModelException e) {
			
		}
		
	}


	@Override
	public void doDelete(DeleteStmt ht) {
		this.doDelete(ht.getFeedname().getFeedname());
		
	}


	@Override
	public void doInsert(InsertStmt ht) {
		Insert ins = new Insert();
		TableDescriptor td;
		try {
			td = this.model.getTableDescriptor(ht.getFeedname()
					.getFeedname());
			
			if (td != null) {
				
					List<DataValue> vals = ht.getDatavalues();

					Entry e = new Entry(td, ht.getDataprovider().getName());
					ins.add(e);

					Datum d;

					for (int j = 0; j < vals.size(); j++) {
						DataValue dv = vals.get(j);
						d = new Datum(td, e, dv.getName(), dv.getValue()
								.doubleValue());
						ins.add(d);
					}

			this.doInsert(ins);	
			} else {
				// TODO ERROR
			}
		} catch (HowlModelException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		
	}


	@Override
	public boolean put(String j) {
		return false;
	}
}
